package com.zeta.demo.es.common.param;

import cn.hutool.core.util.StrUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;

import java.util.ArrayList;
import java.util.List;

/**
 * Es 分页查询参数
 *
 * @author gcc
 */
@Schema(description = "ElasticSearch分页查询参数")
public class EsPageParam<T> {

    /** 当前页 ES页码下标从0开始 */
    @Schema(description = "当前页", example = "0", requiredMode = Schema.RequiredMode.REQUIRED)
    private Integer page = 0;

    /** 每页显示条数 */
    @Schema(description = "每页显示条数", example = "10", requiredMode = Schema.RequiredMode.REQUIRED)
    private Integer limit = 10;

    /** 查询条件 */
    @Schema(description = "查询条件", requiredMode = Schema.RequiredMode.REQUIRED)
    @Valid
    private T model;

    /** 排序字段 */
    @Schema(description = "排序字段", allowableValues = {"id", "createTime", "updateTime"}, example = "id", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private String sort = "id";

    /** 排序规则 */
    @Schema(description = "排序规则", allowableValues = {"desc", "asc"}, example = "desc", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private String order = "desc";


    public EsPageParam() {
    }

    public EsPageParam(Integer page, Integer limit) {
        this.page = page;
        this.limit = limit;
    }

    public EsPageParam(Integer page, Integer limit, T model) {
        this.page = page;
        this.limit = limit;
        this.model = model;
    }

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public T getModel() {
        return model;
    }

    public void setModel(T model) {
        this.model = model;
    }

    public String getSort() {
        return sort;
    }

    public void setSort(String sort) {
        this.sort = sort;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    /**
     * 构建ES分页对象
     *
     * @return Pageable
     */
    public Pageable buildPage() {
        PageRequest page = PageRequest.of(this.page, this.limit);

        // 判断是否有排序
        if (StrUtil.isBlank(this.sort)) {
            return page;
        }

        // 处理排序
        List<Order> orders = new ArrayList<>();
        String[] sortArr = StrUtil.splitToArray(this.sort, StrUtil.COMMA);
        String[] orderArr = StrUtil.splitToArray(this.order, StrUtil.COMMA);
        for (int i = 0; i < sortArr.length ; i++) {
            // 驼峰转下划线
            String sortField = StrUtil.toUnderlineCase(sortArr[i]);
            orders.add(
                    StrUtil.equalsAny(orderArr[i], "asc", "ascending") ?
                            Order.asc(sortField) : Order.desc(sortField)
            );
        }

        return page.withSort(Sort.by(orders));
    }
}
